<?php
namespace App\Http\Controllers\Saas;
// 微购儿控制器

use App\Http\Config\ErrorCode;
use App\Library\Tools;
use App\Models\Admin\AdminUser;
use App\Models\Saas\Mall;
use App\Models\Saas\Setting;
use App\Models\Saas\UserManager;
use App\Models\User\UserSession;
use App\Models\video\VideoSettingModel;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class WeController extends BaseController
{
    private $oauth_conf = [
        "getUserInfo" => "/oauth/getUserInfo", // 获取用户基本信息地址
        "changePassword" => "/oauth/modifyUserPwd", //修改密码地址
    ];
    private $key = "-----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAxWX0IJTMRxXoz0ap
/eKAaVKIKNv4O0JDaH/P/HkllziedndSRviDig/i676D+XdhZAk+EwWUAFfRc7eU
eX8o6wIDAQABAkBXzNdfPo/19lrNByNJV9vB/QGvGtg4k2qkKmV6aPA9aBs5SyNA
kk9c2s+rSYTK/poEblvJrgXXPqPD0ROSF8qBAiEA8C3yo87q+db19ZvFzU+8b53C
SWudLN5b+6OmaLG1TksCIQDSZppQ44hmoYkRxmo2plP9tY15eZoLOZ7/t5wysMRr
4QIgWg4QZYVHK6iDDrV6pDHaiMtRNvBHvbQeLys8URMY1SMCIGmnmGpyN/bBu2Ev
r/qNf7PxzX9orxBf+RYUj91sotZBAiEA3fp8+NHab3D9oc8/w04A7JHQn6Zojqbo
EcAzKI0tiM0=
-----END PRIVATE KEY-----"; // 私钥
    private $field = [
        "appId", "wsDomain", "id", "name", "secret", "sign", "token", "validTime", //"source"
    ]; // 填入数据库需要存储的表字段
    private $fieldMsg = [
        "appId" => "小程序appId", "wsDomain" => "接口地址", "id" => "应用ID", "name" => "应用名称",
        "secret" => "小程序密钥", "sign" => "签名", "token" => "用户信息token", "validTime" => "应用有效期",
        "source" => "系统来源"
    ];
    private $params;

    public function __construct(Request $request)
    {
        $this->params = $request->input();
        $this->noCheckTokenAction = ["initializeData", "toLogin", "toModifyTime", "updateInfo", "getInfo"];
        parent::__construct($request);
        if(!empty($request["wsDomain"])){
            $this->oauth_conf["getUserInfo"] = $request["wsDomain"] . $this->oauth_conf["getUserInfo"];
            $this->oauth_conf["changePassword"] = $request["wsDomain"] . $this->oauth_conf["changePassword"];
        }
    }

    //获取用户信息
    public function getUserInfo($token, &$msg = ''){
        if(empty($token)){
            return false;
        }
        $currentUrl = $this->oauth_conf["getUserInfo"]; //获取用户基本信息地址
        list($server_token, $login_token) = explode("-", $token);
        $result = json_decode(Tools::curl($currentUrl, json_encode(["token" => $login_token])), true);
        if($result["code"] === 0 && isset($result["data"])){
            return $result["data"];
        }
        $msg = $result['msg'];
        return false;
    }

    // 自动交付生成数据
    public function initializeData(){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        foreach ($this->field as $field) {
            if(!isset($this->params[$field])){
                return $this->return_result(ErrorCode::code("params_not_exist", $this->fieldMsg[$field]));
            }
        }
        $sign = $this->getSign($this->params);
        if($sign != $this->params["sign"]){
            return $this->return_result(ErrorCode::code("customized", "签名错误"));
        }
        if(!$userData = $this->getUserInfo($this->params["token"], $msg)){
            return $this->return_result(ErrorCode::code("customized", $msg));
        }
        $this->params["validTime"] = !is_numeric($this->params["validTime"]) ? strtotime($this->params["validTime"]) : $this->params["validTime"];
        $adminData = $this->checkAccount($userData);
        if(isset($adminData["code"])){
            return $this->return_result($adminData);
        }
        if(!$adminData["id"]){
            return $this->return_result(ErrorCode::code("customized", "创建账号失败"));
        }
        $mallData = $this->checkMall($adminData);
        if(isset($mallData["code"])){
            return $this->return_result($mallData);
        }
        if(!$mallData["id"]){
            return $this->return_result(ErrorCode::code("customized", "创建系统失败"));
        }
        $id = !empty($this->params["permissionId"]) ? $this->params["permissionId"] : 1;
        $method = "generatePermission{$id}";
        if(method_exists($this, $method)) {
            $this->$method($mallData["id"]);
        }else{
            $method = "generatePermission1";
            $this->$method($mallData["id"]);
        }
        global $scf_data;
        $this->returnData["data"] = [
            "url" => (isset($scf_data["host"]) ? $scf_data["host"] : request()->getSchemeAndHttpHost())."/saas/initialize/login",
            "version" => @file_get_contents(public_path().'/version.txt'),
        ];
        return $this->return_result($this->returnData);
    }

    // 检查系统
    public function checkMall($managerData){
        $source = !empty($this->params["source"]) ? $this->params["source"] : null;
        $mallData = Mall::getFields("id,expired_time", ["instance_id" => $this->params["id"], "manager_id" => $managerData["id"], "source" => $source], true, false);
        if(empty($mallData)){ // 没有要创建了
            $adminUserModel = new AdminUser();
            $id = $adminUserModel->adminUserInsert(["password" => bcrypt($managerData["username"]), "name" => $managerData["username"], "position" => "超级管理员"]);
            if(!$id){
                return ErrorCode::code("customized", "添加账户失败");
            }
            $adminData = UserManager::query()->where(["id" => $managerData["id"]])->select(["expired_time", "app_count"])->first();
            if(empty($this->params["validTime"])) {
                $this->params["validTime"] = $adminData["expired_time"];
            }else{
                $this->params["validTime"] = !is_numeric($this->params["validTime"]) ? strtotime($this->params["validTime"]) : $this->params["validTime"];
            }
            $mallId = Mall::query()->insertGetId([
                "instance_id" => $this->params["id"], "manager_id" => $managerData["id"], "admin_id" => $id, "name" => $this->params["name"],
                "expired_time" => $this->params["validTime"], "source" => $source, "create_time" => time()
            ]);
            if(isset($mallId["code"])){
                return $mallId;
            }
            $adminUserModel->newQuery()->where("id", $id)->update(["mall_id" => $mallId]);
            $settingData = Setting::getFields("site_title,seo_title");
            global $scf_data;
            DB::table('configs')->insert([
                'mall_id' => $mallId, "title" => !empty($settingData["siteTitle"]) ? $settingData["siteTitle"] : "crm",
                "seo_title" => !empty($settingData["seoTitle"]) ? $settingData["seoTitle"] : "",
                "env" => !empty($scf_data["IS_SCF"]) ? "CLOUD" : "LOCAL", "site_status" => 1,
                "member_wechat_appid" => $this->params["appId"], "member_wechat_secret" => $this->params["secret"]
            ]);
            DB::table("annual_leave")->insert(['mall_id' => $mallId]);
            DB::table('home_page')->insert([
                ['mall_id' => $mallId, "name" => "轮播", "position" => "1", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 1, 'auth_id' => 1],
                ['mall_id' => $mallId, "name" => "公告", "position" => "2", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 1, 'auth_id' => 2],
                ['mall_id' => $mallId, "name" => "插件", "position" => "3", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 1, 'auth_id' => 3],
                ['mall_id' => $mallId, "name" => "推荐", "position" => "4", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 1, 'auth_id' => 5],
                ['mall_id' => $mallId, "name" => "新闻", "position" => "5", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 1, 'auth_id' => 4],
                ['mall_id' => $mallId, "name" => "导航", "position" => "6", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 1, 'auth_id' => 11],
                ['mall_id' => $mallId, "name" => "轮播", "position" => "1", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 2, 'auth_id' => 6],
                ['mall_id' => $mallId, "name" => "公告", "position" => "2", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 2, 'auth_id' => 7],
                ['mall_id' => $mallId, "name" => "插件", "position" => "3", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 2, 'auth_id' => 8],
                ['mall_id' => $mallId, "name" => "推荐", "position" => "4", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 2, 'auth_id' => 10],
                ['mall_id' => $mallId, "name" => "新闻", "position" => "5", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 2, 'auth_id' => 9],
                ['mall_id' => $mallId, "name" => "导航", "position" => "6", "status" => 1, 'updated_at' => Carbon::now(), 'type' => 2, 'auth_id' => 12],
            ]);
            $mallData = Mall::getFields("id,expired_time", ["id" => $mallId], true, false);
        }
        if (!empty($mallData["expiredTime"]) && $mallData["expiredTime"] <= time()) {
            return ErrorCode::code("mall_expired");
        }
        return $mallData;
    }

    // 检查账号
    public function checkAccount($userData){
        $adminData = UserManager::query()->where("auth_id", $userData["uid"])->select(["id", "username", "expired_time", "mobile"])->first();
        if(empty($adminData)){ // 没账号，创建新账号
            UserManager::query()->insert([
                "auth_id" => $userData["uid"], "avatar" => $userData["avatarUrl"], "username" => $userData["account"],
                "password" => bcrypt($userData["account"]), "mobile" => $userData["mobile"],
                "remark" => "平台自动创建", "type" => 2, "expired_time" => null, "create_time" => time()
            ]);
            $adminData = UserManager::query()->where("auth_id", $userData["uid"])->select(["id", "username", "expired_time", "mobile"])->first()->toArray();
        }else{
            $adminData = $adminData->toArray();
            if(!$adminData["mobile"]){
                UserManager::query()->where("id", $adminData["id"])->update(["mobile" => $userData["mobile"]]);
            }
        }
        if(!empty($adminData["expired_time"]) && $adminData["expired_time"] <= time()){
            return ErrorCode::code('account_expired');
        }
        return $adminData;
    }

    // 登录
    public function toLogin(){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        if(!isset($this->params["loginToken"])){
            return $this->return_result(ErrorCode::code("params_not_exist", "免登录token"));
        }
        if(!isset($this->params["id"])){
            return $this->return_result(ErrorCode::code("params_not_exist", "实例应用ID"));
        }
        if(!$userData = $this->getUserInfo($this->params["loginToken"], $msg)){
            return $this->return_result(ErrorCode::code("customized", $msg));
        }
        $adminData = $this->checkAccount($userData);
        if(isset($adminData["code"])){
            return $this->return_result($adminData);
        }
        if(!$adminData["id"]){
            return $this->return_result(ErrorCode::code("customized", "登录失败"));
        }
        $this->params["source"] = !empty($this->params["source"]) ? $this->params["source"] : "";
        $mallData = Mall::getFields("id,expired_time,admin_id", [
            "instance_id" => $this->params["id"], "manager_id" => $adminData["id"], "source" => $this->params["source"]
        ], true, false);
        if(empty($mallData)){
            return $this->return_result(ErrorCode::code("customized", "系统不存在，请联系管理员"));
        }
        if (!empty($mallData["expiredTime"]) && $mallData["expiredTime"] <= time()) {
            return $this->return_result(ErrorCode::code("mall_expired"));
        }
        $userSessionModel = new UserSession();
        $session_id = $userSessionModel->setSession(['admin_id' => $mallData["adminId"]]);
        global $scf_data;
        if(empty($scf_data)) {
            header('Location: ' . request()->getSchemeAndHttpHost()."/index.html#/homepage/index?SaaSToken={$session_id}&SaaSId={$mallData["id"]}");exit;
        }else{
            $js = " <script language = 'javascript' type = 'text/javascript' >";
            $js .= "window.location.href ='".$scf_data["host"]."/index.html#/homepage/index?SaaSToken={$session_id}&SaaSId={$mallData["id"]}"."'";
            $js .= " </script > ";
            return $js;
        }
    }

    // 信息
    public function getInfo(){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        if(!isset($this->params["loginToken"])){
            return $this->return_result(ErrorCode::code("params_not_exist", "免登录token"));
        }
        if(!isset($this->params["id"])){
            return $this->return_result(ErrorCode::code("params_not_exist", "实例应用ID"));
        }
        if(!$userData = $this->getUserInfo($this->params["loginToken"], $msg)){
            return $this->return_result(ErrorCode::code("customized", $msg));
        }
        $adminData = $this->checkAccount($userData);
        if(isset($adminData["code"])){
            return $this->return_result($adminData);
        }
        if(!$adminData["id"]){
            return $this->return_result(ErrorCode::code("customized", "登录失败"));
        }
        $this->params["source"] = !empty($this->params["source"]) ? $this->params["source"] : "";
        $mallData = Mall::getFields("id", [
            "instance_id" => $this->params["id"], "manager_id" => $adminData["id"], "source" => $this->params["source"]
        ], true, false);
        if(empty($mallData)){
            return $this->return_result(ErrorCode::code("customized", "系统不存在，请联系管理员"));
        }
        global $scf_data;
        $this->returnData["data"] = ["url" => (isset($scf_data["host"]) ? $scf_data["host"] : request()->getSchemeAndHttpHost())."/#/login?system={$mallData["id"]}"];
        return $this->return_result($this->returnData);
    }

    // 修改到期时间
    public function toModifyTime(){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        if(!isset($this->params["token"])){
            return $this->return_result(ErrorCode::code("params_not_exist", "免登录token"));
        }
        if(!isset($this->params["id"])){
            return $this->return_result(ErrorCode::code("params_not_exist", "实例应用ID"));
        }
        if(!$userData = $this->getUserInfo($this->params["token"], $msg)){
            return $this->return_result(ErrorCode::code("customized", $msg));
        }
        $adminData = $this->checkAccount($userData);
        if(isset($adminData["code"])){
            return $this->return_result($adminData);
        }
        if(!$adminData["id"]){
            return $this->return_result(ErrorCode::code("customized", "账号信息不存在"));
        }
        $this->params["source"] = !empty($this->params["source"]) ? $this->params["source"] : "";
        $mallData = Mall::getFields("id", ["instance_id" => $this->params["id"], "manager_id" => $adminData["id"], "source" => $this->params["source"]], true, false);
        if(empty($mallData)){
            return $this->return_result(ErrorCode::code("customized", "系统不存在，请联系管理员"));
        }
        $this->params["validTime"] = !is_numeric($this->params["validTime"]) ? strtotime($this->params["validTime"]) : $this->params["validTime"];
        $res = Mall::doUpdate(["expired_time" => $this->params["validTime"]], ["id" => $mallData["id"]]);
        if($res || $res === 0){
            $this->returnData["msg"] = "修改成功";
        }else{
            $this->returnData = ErrorCode::$admin_enum["fail"];
            $this->returnData["msg"] = "修改失败";
        }
        return $this->return_result($this->returnData);
    }

    // 修改商城基本信息
    public function updateInfo(){
        if($this->returnData["code"] !== 0){
            return $this->return_result($this->returnData);
        }
        foreach (["id", "name", "appId", "secret", "uid", "source", "sign"] as $field) {
            if(!isset($this->params[$field])){
                return ErrorCode::code("params_not_exist", $field);
            }
            $this->params[$field] = trim($this->params[$field]);
        }
        $sign = $this->getSign($this->params);
        if($sign != $this->params["sign"]){
            return ErrorCode::code("customized", "签名错误");
        }
        $adminId = UserManager::query()->where("auth_id", $this->params["uid"])->value("id");
        $mallData = Mall::getFields("id", ["instance_id" => $this->params["id"], "manager_id" => $adminId, "source" => $this->params["source"]], true, false);
        if(empty($mallData)){
            return ErrorCode::code("customized", "商城不存在，请联系管理员");
        }
        Mall::doUpdate(["name" => $this->params["name"]], ["id" => $mallData["id"]]);
        if(!empty($this->params['type']) && $this->params['type'] == 'vod'){
            if(VideoSettingModel::query()->where(["mall_id" => $mallData['id']])->count()){
                VideoSettingModel::query()->where(["mall_id" => $mallData['id']])->update(["app_id" => $this->params["appId"], "app_secret" => $this->params["secret"]]);
            }else{
                VideoSettingModel::query()->insert(["mall_id" => $mallData['id'], "app_id" => $this->params["appId"], "app_secret" => $this->params["secret"]]);
            }
        }else {
            DB::table('configs')->where("mall_id", $mallData["id"])->update([
                "member_wechat_appid" => $this->params["appId"], "member_wechat_secret" => $this->params["secret"]
            ]);
        }
        return $this->return_result($this->returnData);
    }

    // 生成签名
    public function getSign($params){
        unset($params['sign']);
        ksort($params);
        reset($params);

        $pairs = array();
        foreach ($params as $k => $v) {
            if(!empty($v)){
                $pairs[] = "$k=$v";
            }
        }
        $arr = implode('&', $pairs);
        $priKeyId = openssl_pkey_get_private($this->key);
        $signature = '';
        openssl_sign($arr, $signature, $priKeyId, OPENSSL_ALGO_MD5);
        openssl_free_key($priKeyId);
        return base64_encode($signature);
    }

    // 权限1 - 可美视频
    public function generatePermission1($mallId){
        $permission = [
            ["id" => 88, "name" => 'admin.configs'],
            ["id" => 1, "name" => "admin.permission"], ["id" => 28, "name" => "admin.member"], ["id" => 229, "name" => "admin.pluginCenter"],
            ["id" => 253, "name" => "admin.videoBlogger"],
        ];
        $permissionId = [];
        foreach ($permission as $vv){
            $data = DB::table('admin_permissions')->select('id', 'name', 'label', 'cid', 'display', 'description', 'show_mode')->where(['id' => $vv['id'], 'name' => $vv["name"]])->orWhere('cid', $vv["id"])->get();
            if (!empty($data)) {
                $data = json_decode(json_encode($data), true);
                foreach ($data as $item) {
                    $item["auth_id"] = $item["id"];
                    $item["mall_id"] = $mallId;
                    $item["display"] = 0;
                    if($vv["id"] == "253"){
                        $item["show_mode"] = 0;
                    }
                    $cus_res = DB::table('permissions')->where('mall_id', $mallId)->where("auth_id", $item["id"])->first();
                    unset($item["id"]);
                    if (!empty($cus_res->id)) {  //存在就修改
                        DB::table('permissions')->where('id', $cus_res->id)->update($item);
                        $permissionId[] = $cus_res->id;
                    } else {
                        $id = DB::table('permissions')->insertGetId($item);
                        $permissionId[] = $id;
                    }
                }
            }
        }
        $this->createRolePermission($mallId, $permissionId);
        Mall::doUpdate(["type" => "vod"], ["id" => $mallId]);
    }

    // 权限1
    public function generatePermission2($mallId){
        $permission = [
            ["id" => 1, "name" => "admin.permission"], ["id" => 14, "name" => 'admin.goods'], ["id" => 19, "name" => "admin.index"], ["id" => 28, "name" => "admin.member"],
            ["id" => 88, "name" => 'admin.configs'], ["id" => 39, "name" => "admin.order"], ["id" => 44, "name" => "admin.article"], ["id" => 52, "name" => "admin.finance"],
            ["id" => 112, "name" => "admin.hr"], ["id" => 127, "name" => "admin.wallet"], ["id" => 180, "name" => "admin.wxapp"], ["id" => 229, "name" => "admin.pluginCenter"],
            ["id" => 55, "name" => "admin.customer"], ["id" => 57, "name" => "admin.problem"], ["id" => 183, "name" => "admin.adminWxappPlugin"],
            ["id" => 245, "name" => "admin.superWorkOrder"], ["id" => 174, "name" => "admin.wxappPlugin"], ["id" => 238, "name" => "admin.form.index"],
        ];
        $permissionId = [];
        foreach ($permission as $vv){
            $data = DB::table('admin_permissions')->select('id', 'name', 'label', 'cid', 'display', 'description', 'show_mode')->where(['id' => $vv['id'], 'name' => $vv["name"]])->orWhere('cid', $vv["id"])->get();
            if (!empty($data)) {
                $data = json_decode(json_encode($data), true);
                foreach ($data as $item) {
                    $item["auth_id"] = $item["id"];
                    $item["mall_id"] = $mallId;
                    $item["display"] = 0;
                    $cus_res = DB::table('permissions')->where('mall_id', $mallId)->where("auth_id", $item["id"])->first();
                    unset($item["id"]);
                    if (!empty($cus_res->id)) {  //存在就修改
                        DB::table('permissions')->where('id', $cus_res->id)->update($item);
                        $permissionId[] = $cus_res->id;
                    } else {
                        $id = DB::table('permissions')->insertGetId($item);
                        $permissionId[] = $id;
                    }
                }
            }
        }
        $this->createRolePermission($mallId, $permissionId);
        Mall::doUpdate(["type" => "crm"], ["id" => $mallId]);
    }

    public function createRolePermission($mallId, $permissionId){
        $roleId = DB::table("admin_roles")->insertGetId([
            "mall_id" => $mallId, "name" => "全部功能", "description" => "全部功能", "admin_power" => 0,
            "created_at" => Carbon::now()->toDateTimeString(), "updated_at" => Carbon::now()->toDateTimeString()
        ]);
        foreach ($permissionId as $id){
            DB::table("admin_permission_role")->insert([
                "permission_id" => $id, "role_id" => $roleId
            ]);
        }
    }
}
